import com.arcadedb.database.Database;
import com.arcadedb.database.DatabaseFactory;
import com.arcadedb.database.RID;
import com.arcadedb.graph.Vertex;
import com.arcadedb.query.sql.executor.Result;
import com.arcadedb.query.sql.executor.ResultSet;
import indi.hjhk.log.Logger;

import java.util.Optional;

public class createLink_20 {

    public static void main(String[] args){
        Logger logger = Logger.getPureLogger("createLink");
        logger.logSilent("main reached");
        DatabaseFactory dbFactory=new DatabaseFactory("./databases/test20");
        try(Database db=dbFactory.open()) {

            long tot = 0;

            db.begin();

            //db.command("SQL", "CREATE INDEX ON SnapShotTest(id) NOTUNIQUE");
            //db.command("SQL", "CREATE INDEX ON SnapShotPureOrder(id) NOTUNIQUE");

            db.command("SQL", "TRUNCATE TYPE succ");
            ResultSet succList=db.query("SQL", "SELECT FROM succ");
            if (succList.hasNext()){
                logger.logOnStderr("failed to truncate type succ");
                db.rollback();
                db.close();
                return;
            }
            db.command("SQL", "DROP TYPE succ");

            db.getSchema().createEdgeType("succ");
            db.commit();
            db.begin();

            long offset = 0, size = 50000;
            int count = 1;
            while (count > 0) {
                long startTime = System.currentTimeMillis();
                ResultSet rsSnapShotList = db.query("SQL", String.format("SELECT FROM SnapShot SKIP %d LIMIT %d", offset, size));
                count = 0;
                while (rsSnapShotList.hasNext()) {
                    count++;
                    Result rSnapShot = rsSnapShotList.next();

                    Optional<Vertex> optPred = rSnapShot.getVertex();
                    if (optPred.isEmpty()) continue;
                    Vertex vPred = optPred.get();

                    String pred_id = rSnapShot.getProperty("id");
                    String pred_succId = rSnapShot.getProperty("succId");
                    if (pred_succId == null || pred_succId.equals(pred_id)) continue;

                    ResultSet rsSuccList = db.query("SQL", String.format("SELECT FROM SnapShot WHERE id='%s'", pred_succId));
                    if (!rsSuccList.hasNext()) {
                        //logger.logOnStderr("[ERROR] cannot find valid vertex with id %s, skipped.", pred_succId);
                        continue;
                    }

                    int edgeCount=0;

                    while (rsSuccList.hasNext()) {
                        Result rSucc=rsSuccList.next();

                        Optional<Vertex> optSucc = rSucc.getVertex();
                        if (optSucc.isEmpty()) continue;
                        Vertex vSucc = optSucc.get();

                        String succ_predId = rSucc.getProperty("predId");
                        if (succ_predId.equals(pred_id)) {
                            //System.out.println(String.format("Creating edge from %s[succId=%s] to %s[id=%s]", predRid, pred.getString("succId"), succRid, succ.getString("id")));
                            vPred.newEdge("succ", vSucc, true);
                            edgeCount++;
                        }
                    }

                    if (edgeCount!=1){
                        logger.logOnStdout("[WARNING] %d edge(s) created between vertexes with id %s and %s.", edgeCount, pred_id, pred_succId);
                    }
                }
                db.commit();
                long elapsed = System.currentTimeMillis() - startTime;
                db.begin();
                logger.logOnStdout("Creating edges. offset: %d~%d, timeSpend: %dms)", offset, offset + count - 1, elapsed);
                tot += elapsed;
                offset += size;
            }

            db.commit();
//        succList=db.query("SQL", "SELECT FROM succ");
//        while (succList.hasNext()){
//            Optional<Edge> optEdge= succList.next().getEdge();
//            if (optEdge.isEmpty()) continue;
//
//            Edge edge=optEdge.get();
//            System.out.println(edge.getOutVertex()+" -> "+edge.getInVertex());
//        }
            logger.logOnStdout("Finished creating edges, totalTimeSpend: %dms",tot);
        }
    }
}
